/////////////////////////////////////////////////////////////////////////////
// Name:        standardfunctions.h
// Author:      Nicolay Giraldo
// Created:     15/12/05
// Copyright:   Nicolay Giraldo
/////////////////////////////////////////////////////////////////////////////

#ifndef __standardfunctions_H__
#define __standardfunctions_H__



inline bool fconsp (value* expr)
{
	return (expr && (expr->getType() == t_cons));
}


inline value* consp (value* expr)
{
	return fconsp(expr) ? trueval() : NULL;
}


inline value* not(value* exp)
{
	return exp ? NULL : trueval() ;
}


inline bool fatom (value* expr)
{
	return !fconsp(expr);
}


inline value* atom (value* expr)
{
	return fatom(expr) ? trueval() : NULL;
}


inline value* car(value* dcons)
{
	return (dcons ? ((cons*)dcons)->car : dcons);
}


inline value* cdr(value* dcons)
{
	return (dcons ? ((cons*)dcons)->cdr : dcons);
}


inline value* rplaca (value* dcons, value* expr)
{
	((cons*)dcons)->car = expr;
	return dcons;
}


inline value* rplacd (value* dcons, value* expr)
{
	((cons*)dcons)->cdr = expr;
	return dcons;
}


inline bool fendp (value* dcons)
{
	return (dcons == NULL);
}


inline value* list(value* expr)
{
	return expr;
}


inline value* fcons(value* expr1, value* expr2)
{
	return new cons(expr1, expr2);
}


bool chk_type(value* object, type ptype);


value* type_of (value* expr);


value* sum(value* expr);


value* sus(value* expr, value* expr2);


value* mul(value* expr);


value* fdiv(value* expr, value* expr2);


value* factorial(value* expr);


value* feval(value* expr);


value* list_length (value* dcons);


//internal functions
int fast_list_length (cons* dcons);

value* chk_nil(value* exp);

#endif
